package org.victoriest.server.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import javax.annotation.PostConstruct;

import org.apache.log4j.Logger;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.serialization.ClassResolvers;
import org.jboss.netty.handler.codec.serialization.ObjectDecoder;
import org.jboss.netty.handler.codec.serialization.ObjectEncoder;
import org.victoriest.server.VictoriestClient;
import org.victoriest.server.dto.MessageModel;
import org.victoriest.server.dto.RoomModel;
import org.victoriest.server.handler.ClientHandler;
import org.victoriest.server.protocol.Protocol;
import org.victoriest.server.util.MessageSender;

public class EndrawingClient implements VictoriestClient {

	protected Logger logger = Logger.getLogger(getClass());

	protected String host;
	protected int port;
	protected ClientBootstrap bootstrap;
	protected ChannelPipelineFactory pipelineFactory;
	protected InetSocketAddress address;

	@Override
	public int getPort() {
		return port;
	}

	@Override
	public void setPort(int port) {
		this.port = port;
	}

	@Override
	public String getHost() {
		return host;
	}

	@Override
	public void setHost(String host) {
		this.host = host;
	}

	public EndrawingClient() {
	}

	@PostConstruct
	public void init() {
		ChannelFactory channelFactory = new NioClientSocketChannelFactory(
				Executors.newCachedThreadPool(),
				Executors.newCachedThreadPool());
		bootstrap = new ClientBootstrap(channelFactory);
		bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
			public ChannelPipeline getPipeline() throws Exception {
				ChannelPipeline pipeline = Channels.pipeline();
				pipeline.addLast("encoder", new ObjectEncoder());
				pipeline.addLast(
						"decoder",
						new ObjectDecoder(ClassResolvers
								.cacheDisabled(getClass().getClassLoader())));
				// and then business logic.
				pipeline.addLast("endrawing", new ClientHandler());

				return pipeline;
			}
		});

		address = new InetSocketAddress("127.0.0.1", port);
		// Start the connection attempt.
		ChannelFuture future = bootstrap.connect(address);
		logger.info("---------------- Endrawing Client! ---------------");

		Channel channel = future.getChannel();
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		for (;;) {
			try {
				String line;
				line = in.readLine().trim();
				boolean isQuit = commendUtil(channel, line, in);
				if (isQuit) {
					break;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// Wait until the connection is closed or the connection attempt fails.
		future.getChannel().getCloseFuture().awaitUninterruptibly();

		// Shut down thread pools to exit.
		bootstrap.releaseExternalResources();

	}

	private boolean commendUtil(Channel channel, String line, BufferedReader in)
			throws IOException {

		if (line == null || line.length() < 1) {
			System.out
					.println("1 : ENTER_HALL\n2 : CHAT\n3 : CREATE_ROOM\n4 : ENTER_ROOM\n5 : QUIT_ROOM\n6 : QUIT_HALL");
			return false;
		}
		int protocolType = Integer.parseInt(line);
		switch (protocolType) {
		// ENTER_HALL
		case 1:
			MessageSender.write(channel, Protocol.TYPE_ENTER_HALL_REQ);
			System.out.println("TYPE_ENTER_HALL_REQ");
			return false;
		// CHAT
		case 2:
			System.out.println("输入消息类别: ");
			line = in.readLine().trim();
			int chatType = Integer.parseInt(line);
			MessageModel model = new MessageModel();
			model.setType(chatType);
//			model.setReceiverChannelOrGroupId(1);
//			model.setSenderName("victoriest");
//			model.setSenderChannelId(channel.getId());
			switch(chatType){
			// 广播
			case 1:
				System.out.println("输入消息: ");
				line = in.readLine().trim();
				model.setContent(line);
				model.setReceiverChannelOrGroupId(1);
				break;
			// 组会话
			case 2:
				// TODO 获取组id
				System.out.println("输入消息: ");
				line = in.readLine().trim();
				model.setContent(line);
				break;
			// 私人会话
			case 3:
				// TODO 玩家id
				model.setContent("here is the message");
				break;
			default:
				return false;
			}
			MessageSender.write(channel, Protocol.TYPE_CHAT_REQ, model);
			return false;
		// CREATE_ROOM
		case 3:
			System.out.println("输入组名: ");
			line = in.readLine().trim();
			RoomModel room = new RoomModel(channel.getId(), line);
			MessageSender.write(channel, Protocol.TYPE_CREATE_ROOM_REQ, room);
			return false;
		// ENTER_ROOM
		case 4:
			System.out.println("输入组名: ");
			line = in.readLine().trim();
			MessageSender.write(channel, Protocol.TYPE_ENTER_ROOM_REQ, line);
			return false;
		// QUIT_ROOM
		case 5:
			MessageSender.write(channel, Protocol.TYPE_QUIT_ROOM_REQ);
			System.out.println("TYPE_QUIT_ROOM_REQ");
			return false;
		// QUIT_HALL
		case 6:
			MessageSender.write(channel, Protocol.TYPE_QUIT_HALL_REQ);
			System.out.println("TYPE_QUIT_HALL_REQ");
			return true;
		// FEACH_ROOM
		case 7:
			MessageSender.write(channel, Protocol.TYPE_FEACH_ROOM_REQ);
			System.out.println("TYPE_FEACH_ROOM_REQ");
			return false;
		default:
		}
		System.out.println("未知命令");
		return false;
	}

}
